﻿namespace CpuUsageAPI
{
    using System;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;

    [StructLayout(LayoutKind.Sequential)]
    public struct ProcessTimes
    {
        public DateTime CreationTime;
        public DateTime ExitTime;
        public DateTime KernelTime;
        public DateTime UserTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME RawCreationTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME RawExitTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME RawKernelTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME RawUserTime;
        public void ConvertTime()
        {
            this.CreationTime = this.FiletimeToDateTime(this.RawCreationTime);
            this.ExitTime = this.FiletimeToDateTime(this.RawExitTime);
            this.KernelTime = this.FiletimeToDateTime(this.RawKernelTime);
            this.UserTime = this.FiletimeToDateTime(this.RawUserTime);
        }

        private DateTime FiletimeToDateTime(System.Runtime.InteropServices.ComTypes.FILETIME FileTime)
        {
            try
            {
                if (FileTime.dwLowDateTime < 0)
                {
                    FileTime.dwLowDateTime = 0;
                }
                if (FileTime.dwHighDateTime < 0)
                {
                    FileTime.dwHighDateTime = 0;
                }
                long fileTime = (FileTime.dwHighDateTime << 0x20) + FileTime.dwLowDateTime;
                return DateTime.FromFileTimeUtc(fileTime);
            }
            catch
            {
                return new DateTime();
            }
        }
    }
}

